package net.kehuilai.handler;

import com.alibaba.fastjson.JSON;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import net.kehuilai.model.BaseMessage;
import net.kehuilai.util.StringTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
 * Created by genghz on 16/12/6.
 */
public class ClientHandler extends ChannelInboundHandlerAdapter {

    private static final Logger log = LoggerFactory.getLogger(ClientHandler.class);

    private final ConcurrentMap<String, Thread> waiters = new ConcurrentHashMap<String, Thread>();
    private final ConcurrentMap<String, BaseMessage> response = new ConcurrentHashMap<String, BaseMessage>();

    // 连接成功后
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("[socket_client] client connect");
    }

    // 连接断开
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("[socket_client] client disconnect");
    }

    // 接收server端的消息，并打印出来
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        BaseMessage message = (BaseMessage) msg;
        // 接收并打印客户端的信息
        String msgId = message.getId();

        // session 回复
        if (!StringTool.isEmpty(msgId)) {
            Thread thread = this.waiters.remove(msgId);
            if (thread != null) {
                this.response.put(msgId, message);
                synchronized (thread) {
                    thread.notify();
                }
            }
            System.out.println("id: " + ctx.channel().id().asLongText() + ", msg: " + JSON.toJSONString(message));
        } else {
            System.out.println("id: " + ctx.channel().id().asLongText() + ", msg: " + JSON.toJSONString(message));
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
    }

    public BaseMessage getResponse(String msgId) {
        Thread thread = Thread.currentThread();
        this.waiters.put(msgId, thread);
        synchronized (thread) {
            try {
                thread.wait(300000);
                this.waiters.remove(msgId);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return this.response.remove(msgId);
    }
}
